<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div>124</div>
  </body>
  <script>
    /* 
            面向对象的特点：
                封装、继承和多态

            1.封装
                - 对象就是一个存储不同属性的容器
                - 对象不仅存储属性，还要负责数据的安全
                - 直接添加到对象的属性，并不安全，因为它们可以被任意的修改
                - 如何确保数据的安全：
                    - 私有属性：
                      - 将需要保护的数据设置成私有，只能在类的内部访问
                      - 提供setter和getter方法，来对私有属性进行访问和修改,
                        1.可以控制属性的读写权限
                        2.可以在方法中对属性值进行验证
                    - 封装主要用来保证数据的安全
                    - 实现封装的方式
                        1.属性私有化  加#
                        2.通过个getter和setter方法来操作属性
                            get属性名(){
                                return this.#属性
                            }
                            set 属性名(参数){
                                this.#属性 = 参数
                            }
            
               
        */
    class Person {
      #name = "孙悟空";
      #address = "花果山"; //实例使用#开头就变成了私有属性，私有属性只能在类的内部访问
      #gender = "男";
      constructor(name, age) {
        this.name = name;
        this.age = age;
      }
      sayHello() {
        console.log(this.#address, this.#name); //
      }
      getName() {
        return this.#name;
      }
      setName(name) {
        this.#name = name;
      }
      get gender() {
        // 实例调用 p.gender  读取的时候会触发
        return this.#gender;
      }
      set gender(name) {
        // 实例调用 p.gender="xxx"  进行赋值的时候，会执行
        console.log(name, "name");
        this.#gender = name;
      }
    }
    let p = new Person("张三", 20);

    p.sayHello();
    p.setName("汤神");
    p.sayHello();
    p.gender = "女";
    console.log(p.gender);
  </script>
</html>
